<?php

namespace App\Console\Commands;

use App\Enums\Field;
use App\Models\Library\UsedMaterials;
use Facebook\WebDriver\Exception\NoSuchElementException;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;

class CrawlerZhgDetailCommand extends Command
{
    private string $serverUrl;
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'crawler:zhg-detail {--all : 全量同步}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    public function __construct()
    {
        parent::__construct();
        $this->serverUrl = 'http://localhost:4444';
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $times = 0;
        $query = UsedMaterials::query()->whereNotNull('zhg_detail_path');
        if (!$this->option('all')) $query = $query->where('is_detail_processed', 0);
        $totalCount = $query->count();
        $driver = RemoteWebDriver::create($this->serverUrl, DesiredCapabilities::chrome());
        $query->chunkById(20, function ($usedMaterials) use ($driver, $totalCount, &$times) {
            foreach ($usedMaterials as $usedMaterial) {
                $domain = 'https://zhg.cirs-group.com/';
                $driver->get($domain . $usedMaterial->zhg_detail_path);
                if ($times == 0) {
                    foreach (Field::tmpCooliesArr as $tmpCookie) {
                        $driver->manage()->addCookie($tmpCookie);
                    }
                    $driver->navigate()->refresh();
                    sleep(rand(2, 3));
                    // 点击已知晓按钮
                    $hasKnowCssSelector = "div.ant-modal-body > div.flex.justify-center> div > button";
                    $driver->findElement(WebDriverBy::cssSelector($hasKnowCssSelector))->click();
                }
                sleep(rand(3, 4));
                $driver->executeScript("window.scrollTo(0,document.body.scrollHeight)");
                $mainXpathUrl = '//*[@id="view"]/div';
                $mainElements = $driver->findElements(WebDriverBy::xpath($mainXpathUrl));
                $data = [];
                $data['is_detail_processed'] = true;
                foreach ($mainElements as $key => $mainElement) {
                    $rawText = $mainElement->getText();
                    $rawTextArr = explode("\n", $rawText);
                    switch ($key + 1) {
                        case 1:
                            if (count($rawTextArr) != 3) break;
                            //包含XX剂
                            $effectCssSelector = '#view > div:nth-child(1) > div:nth-child(3)>div.detail-tag-green';
                            $effectElements = $mainElement->findElements(WebDriverBy::cssSelector($effectCssSelector));
                            $zhgEffects = [];
                            foreach ($effectElements as $effectElement) {
                                $zhgEffects[] = $effectElement->getText();
                            }
                            $data['zhg_effects'] = implode(',', $zhgEffects);
                            break;
                        case 2:
                            $rawTextArr = array_slice($rawTextArr, 1);
                            foreach ($rawTextArr as $rawTextItem) {
                                $rawTextItemArr = explode(" ", $rawTextItem);
                                $keyNameZh = Arr::first($rawTextItemArr);
                                $value = implode('', array_slice($rawTextItemArr, 1));
                                $data[Field::usedMaterialDetailsFromZhgMappings[$keyNameZh]] = $value;
                            }
                            break;
                        case 3:
                            $rawTextArr = array_slice($rawTextArr, 1);
                            foreach ($rawTextArr as $rawTextItem) {
                                $rawTextItemArr = explode(" ", $rawTextItem);
                                $keyNameZh = Arr::first($rawTextItemArr);
                                $value = implode('', array_slice($rawTextItemArr, 1));
                                $data[Field::usedMaterialDisablesFromZhgMappings[$keyNameZh]] = !($value == '未列入');
                            }
                            break;
                        case 4:
                            // 重点
                            // 先处理table数据
                            $rawTextArr = explode("▷", $rawText);
                            $rawTextArr = array_slice($rawTextArr, 1);
                            foreach ($rawTextArr as $rawTextItem) {
                                $rawTextItemArr = array_filter(explode("\n", $rawTextItem));
                                $keyNameZh = trim(Arr::first($rawTextItemArr));
                                $detailType = Field::usedMaterialDetailsTypes[$keyNameZh];
                                $rawTextItemArr = array_slice($rawTextItemArr, 1);
                                // 如果长度是6的倍数 则有详情数据
                                if ((count($rawTextItemArr) % 6) == 0) {
                                    foreach (array_chunk($rawTextItemArr, 6) as $tableItem) {
                                        $tmpData = [];
                                        foreach ($tableItem as $tableItemChild) {
                                            $tableItemChildArr = explode(" ", $tableItemChild);
                                            $keyNameZh = Arr::first($tableItemChildArr);
                                            $value = implode('', array_slice($tableItemChildArr, 1));
                                            $tmpData[Field::usedMaterialDetailsNames[$keyNameZh]] = $value;
                                        }
                                        $tmpData['type'] = $detailType;
                                        $data['details'][] = $tmpData;
                                    }

                                }
                            }
                            break;
                        case 5:
                            $data['risk_materials'] = Arr::last($rawTextArr);
                            break;
                        case 6:
                            try {
                                $cirPdfPath = $mainElement->findElement(WebDriverBy::cssSelector("a"))->getAttribute('href');
                                $data['cir_pdf_path'] = $cirPdfPath;
                                break;
                            } catch (NoSuchElementException $exception) {
                                break;
                            }
                        case 7:
                            if (Arr::last($rawTextArr) == '已列入') $data['exist_cites'] = true;
                            break;
                        case 8:
                            if (Arr::last($rawTextArr) == '已列入') $data['exist_iecsc'] = true;
                            break;
                    }
                }
                // 写入数据
                DB::transaction(function () use ($usedMaterial, $data) {
                    $usedMaterial->update($data);
                    foreach (Arr::get($data, 'details', []) as $detailData) {
                        $usedMaterial->details()->create($detailData);
                    }
                });
                sleep(rand(1, 3));
                $times++;
                $this->line('已成功执行 ' . $times . '次，共' . $totalCount . '次。');
            }
        });
        $driver->quit();
    }
}
